<script setup lang="ts">
import {ref, h, reactive, onMounted, computed} from 'vue'
import {NTag, useMessage, type TreeSelectOption} from 'naive-ui'
import {PlusRound} from '@vicons/material';
import {DataTable, ActionColumns} from '@/components/DataTable'
import AddEdit from './components/add_edit.vue'
import CustomIcon from "@components/CustomIcon";
import {getRequest, deleteRequest} from "@/api";
import {hasAnyPermission, checkPermissionForItems} from "@/utils";
import {ModalType} from "@/utils/enums.ts";

const message = useMessage()
const parentTreeSelectOption = ref<TreeSelectOption[]>([])
//新增、编辑表单
const addEditFormVisible = ref(false);
const currentEditData = ref<Recordable>({});
//数据表
const menu_list = ref<InstanceType<typeof DataTable> | null>(null)
const columns = [
  {
    title: '标题',
    key: 'label',
    fixed: 'left',
    minWidth: 240,
  },
  {
    title: '类型',
    key: 'type',
    width: 70,
    align: 'center',
    render(row: { types: number }) {
      let type_text: string;
      let type_color: 'info' | 'success' | 'warning'
      switch (row.types) {
        case 1:
          type_text = '目录';
          type_color = 'info';
          break;
        case 2:
          type_text = '菜单';
          type_color = 'success';
          break;
        default:
          type_text = '按钮';
          type_color = 'warning';
      }
      return h(NTag, {type: type_color}, () => type_text)
    }
  },
  {
    title: '图标',
    key: 'icon',
    width: 80,
    align: 'center',
    render: (row: { icon: string, types: number }) => {
      if (row.types == 3) {
        return h('span', null, '--')
      } else {
        return h(CustomIcon, {
          component: row.icon ? row.icon : 'tabler-List',
          size: 20,
        })
      }

    }
  }, {
    title: '路由名称',
    key: 'name',
    width: 130,
    resizable: true,
    render(row: { types: number, name: string }) {
      const name = row.types === 3 ? '--' : row.name
      return h('span', null, {default: () => name})
    }
  }, {
    title: '权限码',
    key: 'code',
    width: 160,
    resizable: true,
    render(row: { types: number, code: string }) {
      const code = row.types === 1 ? '--' : row.code
      return h('span', null, {default: () => code})
    }
  }, {
    title: '上级菜单',
    key: 'parent',
    resizable: true,
  }, {
    title: '排序',
    key: 'sort',
    width: 100,
    align: 'center',
    resizable: true,
  }, {
    title: '菜单栏中显示',
    key: 'hideMenu',
    align: 'center',
    width: 110,
    resizable: true,
    render(row: { hide_menu: number | boolean }) {
      const show=row.hide_menu == 0
      return h(NTag,
          {
            type: show? 'success' : 'error',
          },
          {
            default: () => (show ? '显示' : '不显示'),
          }
      );
    }
  }, {
    title: '创建时间',
    key: 'created_at',
    width: 175,
    resizable: true,
  },
]
//操作列
const actionPermission = ['menus:update', 'menus:delete']//权限
const displayedActions = computed(() => {
  return checkPermissionForItems(
      actionPermission.map(p => ({perm: p})),
      obj => obj.perm
  )
})

const actionColumnWidth = computed(() => {
  const trueCount = displayedActions.value.filter(item => item).length;
  if (trueCount == 1) {
    return 50
  } else {
    return 90
  }
})

const showActionColumn = computed(() => hasAnyPermission(actionPermission))
const operationColumns = reactive({
  width: actionColumnWidth.value,
  isShow: showActionColumn.value,
  render(row: Recordable) {
    return h(ActionColumns, {
      actions: [
        {
          label: '编辑',
          type: 'primary',
          permission: actionPermission[0],
          onClick: () => {
            const currentData=JSON.parse(JSON.stringify(row))
            delete currentData.children
            currentEditData.value = currentData;
            addEditFormVisible.value = true;
          }
        },
        {
          label: '删除',
          type: 'error',
          permission: actionPermission[1],
          popConfirm: {
            content: `确定删除当前${row.types == 1 ? '目录' : row.types == 2 ? '菜单' : '按钮'}吗？`,
            onPositiveClick: () => {
              deleteRequest('/menus/delete', row.id).then((res) => {
                if (res.code == 200) {
                  message.success(res.message, {
                    duration: 1500,
                    onLeave() {
                      menu_list.value?.reload()
                    }
                  })
                } else {
                  message.error(res.message || '删除失败！')
                }
              })
            },
          }
        },
      ],
    })
  }
})
//关闭模态框
const handleModalClose = (modalType: ModalType) => {
  if (!menu_list.value) return
  if (modalType === ModalType.SEARCH) {
    menu_list.value.searchData?.()
    getParentData()
  } else {
    menu_list.value.reload?.()
  }
}
//获取上级数据
const getParentData = async () => {
  await getRequest('/menus/menus_select').then(res => {
    const data: TreeSelectOption[] = res.data as TreeSelectOption[];
    parentTreeSelectOption.value = [{
      label: '顶级目录',
      key: 0
    }, ...data]
  })
}
onMounted(() => {
  getParentData();
})
</script>

<template>
  <div>
    <n-card>
      <data-table ref="menu_list" :columns="columns"
                  :action-column="operationColumns"
                  url="/menus/lists"
                  :pagination="false">
        <template #toolBarLeft>
          <n-button type="primary" ghost  v-permission="['menus:save']"
                    @click="()=>(addEditFormVisible= true)">
            <template #icon>
              <n-icon>
                <PlusRound/>
              </n-icon>
            </template>
            新增
          </n-button>
        </template>
      </data-table>
    </n-card>
    <!--  新增、编辑菜单数据  -->
    <component :is="AddEdit" v-model:visible="addEditFormVisible"
               :form-data="currentEditData"
               :parent-tree-select-option="parentTreeSelectOption"
               @close-modal="handleModalClose"/>
  </div>
</template>
<style scoped lang="scss">

</style>
